/*
 * LiveStream.h
 *
 *  Created on: Mar 27, 2013
 *      Author: root
 */

#ifndef LIVESTREAM_H_
#define LIVESTREAM_H_

#include "FLV.h"
#include "MPEGTS.h"
#include "http.h"

#define INFO_MAX_SIZE 8192
#define MAX_STREAM_COUNT 1000
/**
*stream active state
**/
enum STREAM_STATE
{
	ST_CLOSE,
	ST_ACTIVE,
};
/*
*live config info
*/
struct live_config_info
{
	uint16_t id;
	uint16_t relation_id;
	char info[INFO_MAX_SIZE];
	int video_flag;
	int audio_flag;
	int vidoe_playload_type;
	int audio_playload_type;
	uint32_t video_sample_freq;
	uint32_t audio_sample_freq;
	uint16_t audio_channel;
	size_t info_len;
	live_config_info()
	{
		id = 0;
		relation_id = 0;
		memset(info,'\0',INFO_MAX_SIZE);
		info_len = 0;
		video_flag = 0;
		audio_flag = 0;

		vidoe_playload_type = 0;
		audio_playload_type = 0;

		video_sample_freq = 90000;
		audio_sample_freq = 90000;
		audio_channel = 1;
	}
};
/*
*media stream
*/
struct stream
{
	uint16_t stream_id;
	HTTP_MIME fmt;
	void * sFormatConetext;
	smart_lock * pLock;
	mediaInfo media_data;
	STREAM_STATE state;
	stream()
	{
		stream_id = 0;
		fmt = NONE;
		sFormatConetext = NULL;
		media_data.priva_data = NULL;
		media_data.priva_data_len = 0;
		memset(media_data.audio_config,'\0',sizeof(media_data.audio_config));
		media_data.audio_config_len = 0;
		state = ST_CLOSE;
		pLock = new smart_lock();
	}
};

/**
 *LiveStream class
 */
class LiveStream {
public:
	LiveStream();
	virtual ~LiveStream();

	/*
	* init live
	*/
	int init_live_stream(uint16_t max_live_channel);
	int init_live_stream(uint16_t max_live_channel,int is_make_m3u8_list_flag);

	/*
	* init stream and find,check, free stream
	*/
	int init_stream(uint16_t stream_id,HTTP_MIME fmt,CodecID codec_id);
	int init_stream(uint16_t stream_id,HTTP_MIME fmt);
	int free_stream(uint16_t stream_id);

	/*
	* write ,read stream data and info
	*/
	int write_buf(uint16_t stream_id,char * buf,u_long len);
	int read_buf(uint16_t stream_id,char * buf,u_long len,uint64_t &pkt_index,u_long &offset,uint64_t &readlen);

	/*
	* init ts
	*/
	int init_ts_ctx(uint16_t stream_id,uint64_t &pkt_index,u_long &offset,uint64_t &readLen);

	/*
	* read_m3u8_list info
	*/
	size_t read_m3u8_list(uint16_t stream_id,char * buf,size_t buf_len,const char * sid);

	/*
	* get live resource info
	*/
	int get_current_stream_count(void);
	int get_free_stream_count(void);
	int get_current_packet_count(void);
	int get_free_packet_count(void);
	int get_current_ts_packet_count(void);
	int get_free_ts_packet_count(void);

protected:
	/*
	* find_stream
	*/
	stream * find_stream(uint16_t stream_id);

	/*
	* init stream media info
	*/
	int init_media_info(uint16_t stream_id);

	/*
	* add ,get ,free live config
	*/
	int add_live_config_info(uint16_t id,const char * buf);
	int add_live_config_info(live_config_info *pconfig);
	live_config_info * get_live_config_info(uint16_t id);
	void free_live_config_info(uint16_t id);

	/*
	* create mu38
	*/
	size_t create_m3u8_list(TSContext *c,char * buf,size_t buf_len,const char * sid = NULL);

	/*
	* flv stream handle
	*/
	int check_flv_stream(FLVContext * flvFromat,AVPacket *pkt);
	int handle_flv_stream(FLVContext * flvFromat,char * buf,u_long len);
	int read_flv_stream_packet(FLVContext *flvContent,char * buf,u_long len,uint64_t &pkt_index,u_long &offset,uint64_t &readlen);

	/*
	* ts stream handle
	*/
	int split_ts_stream(TSContext *c,char * buf,u_long len);
	int packet_ts_stream(TSContext *c , uint8_t * packet, u_long pkt_len);
	int handle_ts_stream(TSContext *c,uint8_t * buf,u_long len);
	int read_ts_packet(TSContext *c,char * buf,u_long len,uint64_t &pkt_index,u_long &offset,uint64_t &readlen);

	/*
	*packet chunk
	*/
	virtual bool stream_init_chunk(uint16_t streamid,uint8_t fmt,uint8_t * pArgData,size_t len);
	virtual bool stream_packet_chunk(uint16_t streamid,uint8_t * pSrcData,size_t len);
	virtual bool stream_close_chunk(uint16_t streamid);
	virtual	int  stream_log(int nloglvl,const char * lpszFormat, ...);
private:
	/*
	*live stream cach buf
	*/
	StreamBuffer sbuf;

	/*
	* stream list
	*/
	int  current_stream_count;
	stream * liveStream[MAX_STREAM_COUNT];
	queue<stream *> free_steam_list;
	live_config_info * live_info[MAX_STREAM_COUNT];
	smart_lock stream_Lock;

	/*
	* stream config
	*/
	bool is_make_m3u8_list;
	int  m3u8listcount;
	int  m3u8listpktcount;

	/*
	*limit stream cach packet count
	*/
	uint16_t stream_limit_packet_count;
};

#endif /* LIVESTREAM_H_ */
